import { GameState } from './Position';
import { GameBoard } from './GameBoard';
import { Tetromino } from './Tetromino';
import { ScoreManager } from '../managers/ScoreManager';
import { GameTimer } from '../managers/GameTimer';
import { AudioManager } from '../managers/AudioManager';
import { GameController, KeyAction } from '../controllers/GameController';
import { GameRenderer } from '../renderers/GameRenderer';

/**
 * 俄罗斯方块主游戏类
 */
export class TetrisGame {
    private board: GameBoard;
    private currentTetromino: Tetromino | null = null;
    private nextTetromino: Tetromino;
    private state: GameState = GameState.READY;
    private scoreManager: ScoreManager;
    private timer: GameTimer;
    private audioManager: AudioManager;
    private controller: GameController;
    private renderer: GameRenderer;
    private animationFrameId: number | null = null;

    // 游戏配置
    private readonly BOARD_WIDTH = 10;
    private readonly BOARD_HEIGHT = 20;
    private readonly START_X = 3;
    private readonly START_Y = 0;

    constructor(canvas: HTMLCanvasElement) {
        this.board = new GameBoard();
        this.scoreManager = new ScoreManager();
        this.timer = new GameTimer();
        this.audioManager = new AudioManager();
        this.controller = new GameController();
        this.renderer = new GameRenderer(canvas);

        // 生成第一个下一个方块
        this.nextTetromino = Tetromino.random();

        // 设置控制器
        this.controller.setHandler((action) => this.handleKeyAction(action));
    }

    /**
     * 开始游戏
     */
    start(): void {
        if (this.state === GameState.PLAYING) {
            return;
        }

        this.reset();
        this.state = GameState.PLAYING;
        this.spawnTetromino();
        this.gameLoop();
    }

    /**
     * 暂停/继续游戏
     */
    pause(): void {
        if (this.state === GameState.PLAYING) {
            this.state = GameState.PAUSED;
            this.audioManager.playRotate();
        } else if (this.state === GameState.PAUSED) {
            this.state = GameState.PLAYING;
            this.timer.reset();
            this.gameLoop();
        }
    }

    /**
     * 重置游戏
     */
    reset(): void {
        this.board.clear();
        this.scoreManager.reset();
        this.timer.reset();
        this.timer.updateLevel(this.scoreManager.getLevel());
        this.state = GameState.READY;
        this.nextTetromino = Tetromino.random();
        this.currentTetromino = null;
    }

    /**
     * 生成新方块
     */
    private spawnTetromino(): void {
        this.currentTetromino = this.nextTetromino;
        this.currentTetromino.position = { x: this.START_X, y: this.START_Y };
        this.nextTetromino = Tetromino.random();

        // 检查游戏是否结束
        if (!this.board.canPlaceTetromino(this.currentTetromino)) {
            this.gameOver();
        }
    }

    /**
     * 处理键盘操作
     */
    private handleKeyAction(action: KeyAction): void {
        if (this.state !== GameState.PLAYING) {
            if (action === KeyAction.PAUSE && this.state === GameState.PAUSED) {
                this.pause();
            } else if (action === KeyAction.RESTART) {
                this.start();
            }
            return;
        }

        if (!this.currentTetromino) return;

        switch (action) {
            case KeyAction.MOVE_LEFT:
                this.moveTetromino(-1, 0);
                break;
            case KeyAction.MOVE_RIGHT:
                this.moveTetromino(1, 0);
                break;
            case KeyAction.MOVE_DOWN:
                this.moveTetromino(0, 1);
                break;
            case KeyAction.ROTATE:
                this.rotateTetromino();
                break;
            case KeyAction.HARD_DROP:
                this.hardDrop();
                break;
            case KeyAction.PAUSE:
                this.pause();
                break;
        }
    }

    /**
     * 移动方块
     */
    private moveTetromino(deltaX: number, deltaY: number): void {
        if (!this.currentTetromino) return;

        this.currentTetromino.move(deltaX, deltaY);

        if (!this.board.canPlaceTetromino(this.currentTetromino)) {
            // 回退移动
            this.currentTetromino.move(-deltaX, -deltaY);
            return;
        }

        this.audioManager.playMove();
    }

    /**
     * 旋转方块
     */
    private rotateTetromino(): void {
        if (!this.currentTetromino) return;

        this.currentTetromino.rotate();

        // 尝试墙踢（Wall Kick）：如果旋转后碰撞，尝试左右移动一格
        if (!this.board.canPlaceTetromino(this.currentTetromino)) {
            // 尝试右移
            this.currentTetromino.move(1, 0);
            if (this.board.canPlaceTetromino(this.currentTetromino)) {
                this.audioManager.playRotate();
                return;
            }
            this.currentTetromino.move(-1, 0);

            // 尝试左移
            this.currentTetromino.move(-1, 0);
            if (this.board.canPlaceTetromino(this.currentTetromino)) {
                this.audioManager.playRotate();
                return;
            }
            this.currentTetromino.move(1, 0);

            // 回退旋转
            this.currentTetromino.rotateBack();
            return;
        }

        this.audioManager.playRotate();
    }

    /**
     * 硬下降（一次到底）
     */
    private hardDrop(): void {
        if (!this.currentTetromino) return;

        let dropDistance = 0;
        while (this.board.canPlaceTetromino(this.currentTetromino)) {
            this.currentTetromino.move(0, 1);
            dropDistance++;
        }
        // 回退最后一步
        this.currentTetromino.move(0, -1);
        dropDistance--;

        if (dropDistance > 0) {
            this.scoreManager.addHardDrop(dropDistance);
            this.audioManager.playHardDrop();
            this.lockTetromino();
        }
    }

    /**
     * 锁定方块并检查消除
     */
    private lockTetromino(): void {
        if (!this.currentTetromino) return;

        this.board.placeTetromino(this.currentTetromino);
        const linesCleared = this.board.clearLines();

        if (linesCleared > 0) {
            this.scoreManager.addLines(linesCleared);
            this.timer.updateLevel(this.scoreManager.getLevel());
            this.audioManager.playClear(linesCleared);
        }

        this.spawnTetromino();
    }

    /**
     * 自动下降
     */
    private autoDrop(): void {
        if (!this.currentTetromino) return;

        this.currentTetromino.move(0, 1);

        if (!this.board.canPlaceTetromino(this.currentTetromino)) {
            // 回退并锁定
            this.currentTetromino.move(0, -1);
            this.lockTetromino();
        }
    }

    /**
     * 游戏主循环
     */
    private gameLoop(): void {
        if (this.state !== GameState.PLAYING) {
            return;
        }

        const currentTime = performance.now();

        // 检查是否应该自动下降
        if (this.timer.shouldDrop(currentTime)) {
            this.autoDrop();
        }

        // 渲染
        this.render();

        // 继续循环
        this.animationFrameId = requestAnimationFrame(() => this.gameLoop());
    }

    /**
     * 渲染游戏画面
     */
    private render(): void {
        this.renderer.clear();

        // 绘制棋盘
        this.renderer.drawBoard(this.board);

        // 绘制当前方块
        if (this.currentTetromino) {
            this.renderer.drawTetromino(this.currentTetromino);
        }

        // 注意：下一个方块预览和信息将在sidebar的独立canvas中显示
        // 这里只绘制主游戏区域

        // 绘制状态文本
        if (this.state === GameState.PAUSED) {
            this.renderer.drawStatus('暂停');
        } else if (this.state === GameState.GAME_OVER) {
            this.renderer.drawStatus('游戏结束');
        }
    }

    /**
     * 游戏结束
     */
    private gameOver(): void {
        this.state = GameState.GAME_OVER;
        if (this.animationFrameId !== null) {
            cancelAnimationFrame(this.animationFrameId);
            this.animationFrameId = null;
        }
        this.audioManager.playGameOver();
        this.render();
    }

    /**
     * 获取游戏状态
     */
    getState(): GameState {
        return this.state;
    }

    /**
     * 获取下一个方块
     */
    getNextTetromino(): Tetromino {
        return this.nextTetromino;
    }

    /**
     * 获取分数管理器
     */
    getScoreManager(): ScoreManager {
        return this.scoreManager;
    }

    /**
     * 清理资源
     */
    destroy(): void {
        if (this.animationFrameId !== null) {
            cancelAnimationFrame(this.animationFrameId);
        }
        this.controller.destroy();
    }
}

